package marketplace.jpa.dao;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import marketplace.jpa.datas.DataCliente;
import marketplace.jpa.datas.DataContenidoDigital;
import marketplace.jpa.datas.DataReclamo;
import marketplace.jpa.datas.DataValoracion;
import marketplace.jpa.datas.DataVenta;
import marketplace.jpa.datas.DataVersion;
import marketplace.jpa.datas.Estado;
import marketplace.jpa.entities.Cliente;
import marketplace.jpa.entities.ContenidoDigital;
import marketplace.jpa.entities.Reclamo;
import marketplace.jpa.entities.Valoracion;
import marketplace.jpa.entities.Venta;
import marketplace.jpa.entities.Version;
import marketplace.jpa.interfaces.IVentaDAO;

@Stateless
public class VentaDAO implements IVentaDAO {
	
	@PersistenceContext(unitName="Marketplace")
	EntityManager em;
	
	
	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public boolean ingresarValoracion(DataValoracion dv) throws Exception {
		boolean ok = false;
		try {
			Venta v = em.find(Venta.class, dv.getIdVenta());
			
			String fechaVenta = v.getFechaVenta();
			String fechaValoracion = dv.getFecha();

			SimpleDateFormat df = new SimpleDateFormat("dd/MM/yy");
			java.util.Date dVenta = df.parse(fechaVenta);
			java.util.Date dValoracion = df.parse(fechaValoracion);
				
			Calendar fechaAux = Calendar.getInstance(); 
			fechaAux.setTime(dVenta); 
			fechaAux.add(Calendar.DAY_OF_MONTH, 3); 
			Date fechaVentaMasTres = fechaAux.getTime();
			
			if(dValoracion.compareTo(fechaVentaMasTres) != -1)
			{
				if(v.getValoracion() ==  null){
					
				Valoracion valoracion = new Valoracion();
				valoracion.setFecha(dv.getFecha());
				valoracion.setValor(dv.getValor());
				valoracion.setOpinion(dv.getOpinion());
				valoracion.setEstado(Estado.ACTIVO.toString());
				em.persist(valoracion);
				em.flush();
				
				v.setValoracion(valoracion);	
			}
				
			else{
				Valoracion val = em.find(Valoracion.class, v.getValoracion().getIdValoracion());	
				val.setValor(dv.getValor());
				}
				
				ok = true;	
			}

			
		} catch (Exception e) {
			System.out.println("Error DAO Venta (Funcion ingresarValoracion) " + e.getMessage());
		}
		return ok;
		
	}
	
	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public void modificarValoracion(DataValoracion dv) throws Exception {
		try {
			Valoracion v = em.find(Valoracion.class, dv.getIdValoracion());
			v.setOpinion(dv.getOpinion());
			v.setValor(dv.getValor());
			
		} catch (Exception e) {
			System.out.println("Error DAO Venta (Funcion modificarValoracion) " + e.getMessage());
		}
		
	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public void eliminarValoracion(int idv) throws Exception {
		try {
			 Valoracion v = em.find(Valoracion.class, idv);
			 v.setEstado(Estado.INACTIVO.toString());
			 em.flush();
			
		} catch (Exception e) {
			System.out.println("Error DAO Reclamo (Funcion eliminarValoracion) " + e.getMessage());
		}
		
	}

	
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public boolean altaReclamo(DataReclamo dr) throws Exception {
		boolean ok = false;
		try {
			Venta v = em.find(Venta.class, dr.getIdVenta());
			Reclamo r = new Reclamo();
			r.setDescripcion(dr.getDescripcion());
			r.setFecha(dr.getFecha());
			r.setEstado(dr.getEstado().toString());
			r.setVenta(v);
			em.persist(r);
			em.flush();
			
			v.getReclamos().add(r);
			ok = true;
			
			
		} catch (Exception e) {
			System.out.println("Error DAO Reclamo (Funcion altaReclamo): " + e.getMessage());
		}
		return ok;
	}
	
	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public void eliminarReclamo(int idr) throws Exception {
		try {
			
			 Reclamo r = em.find(Reclamo.class, idr);
			 r.setEstado(Estado.INACTIVO.toString());
			 em.flush();
			
		} catch (Exception e) {
			System.out.println("Error DAO Reclamo (Funcion eliminarReclamo) " + e.getMessage());
		}
		
	}	


	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public void modificarReclamo(DataReclamo dr) throws Exception {
		try {
			Reclamo r = em.find(Reclamo.class, dr.getIdReclamo());
			r.setDescripcion(dr.getDescripcion());
			
		} catch (Exception e) {
			System.out.println("Error DAO Reclamo (Funcion modificarReclamo) " + e.getMessage());
		}
		
	}
	
	@Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
	public List<DataVenta> getVentasCliente(String mail) throws Exception {	
		List<DataVenta> ventas = new ArrayList<DataVenta>();
		try{
			Cliente c = em.find(Cliente.class, mail);
			Query q = em.createQuery("select v from Venta v where v.cliente = ?1");
			q.setParameter(1, c);

			if (q.getResultList() !=null ){
				int i=0;
				for(i=0; i<q.getResultList().size();i++){
					DataVenta dv = new DataVenta();
					DataVersion dvers = new DataVersion();
					DataContenidoDigital dc = new DataContenidoDigital(); 
					
					Venta aux = (Venta)q.getResultList().get(i);
					dv.setFechaVenta(aux.getFechaVenta());
					dv.setMonto(aux.getMonto());
					dv.setIdVenta(aux.getIdVenta());
					
					dc.setDescripcion(aux.getContenido().getContDig().getDescripcion());
					dvers.setContDig(dc);
					dvers.setNombre(aux.getContenido().getNombre());
					dv.setVersion(dvers);
					
					ventas.add(dv);
				}
			}
		} 
		catch(Exception e){ System.out.println("Error DAO Ventas (Funcion getVentasCliente): " + e.getMessage()); }				
		return ventas;
	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public boolean ingresarVenta(DataVenta dv) throws Exception {
		boolean ok = false;
		try{
				Venta v = new Venta();
				Version cd = em.find(Version.class, dv.getIdContDigital());
				Cliente u = em.find(Cliente.class, dv.getMailCliente());
				v.setContenido(cd);
				v.setFechaVenta(dv.getFechaVenta());
				v.setMonto(dv.getMonto());
				v.setCliente((Cliente) u);
				cd.setCantDescragas(cd.getCantDescragas()+1);
				em.persist(v);
				ok = true;
			}
			catch(Exception e){
				System.out.println("Error DAO Ventas (Funcion ingresarVentaCliente): " + e.getMessage()); }
		
		return ok;
	}

	@SuppressWarnings("unchecked")
	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public ArrayList<DataVenta> obtenerVentas(){
		ArrayList<DataVenta> venta = new ArrayList<DataVenta>();
		try{	
			List<Venta> ven = new ArrayList<Venta>();
			Query q = em.createQuery("select v from venta v");
			ven = ((List<Venta>) q.getResultList());
			
			for (Venta venta2 : ven) {
				venta.add(new DataVenta(venta2));
			}
		} 
		catch(Exception e){ System.out.println("Error DAO Ventas (Funcion obtenerVentas): " + e.getMessage()); }				
		return venta;
	}
	
	
	
	
	
	
	///////////////////////// VALORACION VERSION //////////////////////////////
	
	
	
	@SuppressWarnings("unchecked")
	@Override	
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public ArrayList<DataVenta> obtenerVentasFULL(int idVersion){
		ArrayList<DataVenta> ventas = new ArrayList<DataVenta>();
		try{		
			Query q = em.createQuery("select v from Venta v where v.contenido.idVersion = ?1");
			q.setParameter(1, idVersion);

			if (q.getResultList() != null ){
				List<Venta> lstVenta = (List<Venta>) q.getResultList();
				for (Venta dv : lstVenta) {					
					DataVenta dVen = new DataVenta(dv);					
					ventas.add(dVen);
				}
			}
		} 
		catch(Exception e){ System.out.println("Error DAO Ventas (Funcion obtenerVentasFULL): " + e.getMessage()); }				
		return ventas;				
	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public List<DataReclamo> getReclamosVenta(int idVenta) throws Exception {
		Venta v = new Venta();
		v= em.find(Venta.class, idVenta);
		List<DataReclamo> reclamos = new ArrayList<DataReclamo>();
		try {
		
			Query q = em.createQuery("select r from Reclamo r where r.venta = ?1");
			q.setParameter(1, v);

			if (q.getResultList() !=null ){
				int i=0;
				for(i=0; i<q.getResultList().size();i++){
				
					if(((Reclamo)q.getResultList().get(i)).getEstado().compareTo(Estado.ACTIVO.toString())==0){
						DataReclamo dr = new DataReclamo();
						DataVenta dv = new DataVenta();
						Reclamo aux = (Reclamo)q.getResultList().get(i);
						dr.setIdReclamo(aux.getIdReclamo());
						dr.setDescripcion(aux.getDescripcion());
						dr.setFecha(aux.getFecha());
						
						Version verAux = ((Reclamo)q.getResultList().get(i)).getVenta().getContenido();
						DataVersion dversion = new DataVersion();
						dversion.setNombre(verAux.getContDig().getDescripcion());
	
						DataCliente dcliente = new DataCliente();
						dcliente.setMail(aux.getVenta().getCliente().getMail());
						dv.setCliente(dcliente);
							
						ContenidoDigital cd = new ContenidoDigital();
						cd = aux.getVenta().getContenido().getContDig();
						DataContenidoDigital dcd = new DataContenidoDigital();
						dcd.setDescripcion(cd.getDescripcion());
						
						dversion.setContDig(dcd);
						dv.setVersion(dversion);
						dr.setVenta(dv);					
										
						reclamos.add(dr);
					}
				}
			} 
		}catch (Exception e) {
			System.out.println("Error DAO Ventas (Funcion getReclamosVenta" + e.getMessage());}
		Collections.sort(reclamos);
		return reclamos;
	}

	@Override
	public DataReclamo buscarReclamo(int idr) throws Exception {
		DataReclamo dr = new DataReclamo();
		try {
			Reclamo r = new Reclamo();
			r= em.find(Reclamo.class, idr);
			dr.setIdReclamo(r.getIdReclamo());
			dr.setDescripcion(r.getDescripcion());
			dr.setFecha(r.getFecha());
			dr.setEstado(Estado.valueOf(r.getEstado()));
			dr.setIdVenta(r.getVenta().getIdVenta());		
			
		}catch (Exception e) {
			System.out.println("Error DAO Ventas (Funcion getReclamosVenta" + e.getMessage());}

		return dr;
	}

	@Override
	public DataVenta buscarVenta(int idv) throws Exception {
		DataVenta dv = new DataVenta();
		try {
			Venta v = new Venta();
			v= em.find(Venta.class, idv);
			
			dv.setIdVenta(v.getIdVenta());
			
			dv.setFechaVenta(v.getFechaVenta());
			dv.setIdContDigital(v.getContenido().getIdVersion());
			if(v.getValoracion() != null)
			dv.setValoracion(v.getValoracion().getValor());
			System.out.println(dv.getIdVenta());

		}catch (Exception e) {
			System.out.println("Error DAO Ventas (Funcion buscarVenta" + e.getMessage());}

		return dv;
	}

	@Override
	public String getDescargasContenidoX() throws Exception {
		
		String resultado="[";
		try{	
			
			for (int i = 12; i > 0; --i) {
				Date hoy = new Date();
				Calendar fechaAux = Calendar.getInstance(); 
				fechaAux.setTime(hoy);
				fechaAux.add(Calendar.MONTH, -i);				
				resultado = resultado + "'" + obtenerMes(fechaAux.getTime()) + "'";
				if(i>1)
				resultado = resultado + "," + " ";	
			}
			resultado = resultado + "]";


				
		} 
		catch(Exception e){ System.out.println("Error DAO Ventas (Funcion getDescargasContenidoX): " + e.getMessage()); }				
		return resultado;
	}

	@Override
	public String getDescargasContenidoY(int idCont) throws Exception {
		String resultado = "[";
		ContenidoDigital c = em.find(ContenidoDigital.class, idCont);
		try {
			
			Query q = em.createQuery("select v from Version v where v.contDig = ?1");
			q.setParameter(1, c);
			
			
			for (int i = 12; i > 0; --i) {
				Date hoy = new Date();
				Calendar fechaAux = Calendar.getInstance(); 
				
				SimpleDateFormat f =new SimpleDateFormat("dd/MM/yy");
 				String formattedDate = f.format(hoy);
				
 				java.util.Date d = f.parse(formattedDate);
 				SimpleDateFormat sdf = new SimpleDateFormat("yy");
 								
				fechaAux.setTime(d);
				fechaAux.add(Calendar.MONTH, -i);
				int mes = fechaAux.get(Calendar.MONTH) + 1;
				String auxiliar;
				
				if(mes<10)
					auxiliar = "0"+mes+"/"+sdf.format(fechaAux.getTime());
				else		
					auxiliar = mes+"/"+sdf.format(fechaAux.getTime());
				
				int sumaDescargasVersion=0;
				
				if(q.getResultList() != null){
				for (int j = 0; j < q.getResultList().size(); j++) {
					
					Query q2 = em.createQuery("select d from Venta d where d.fechaVenta like '%"+auxiliar+"' and d.contenido = ?2");
					q2.setParameter(2, q.getResultList().get(j));
					if(q2.getResultList() != null)
					sumaDescargasVersion = sumaDescargasVersion + q2.getResultList().size();
					
				}
		 		resultado = resultado + sumaDescargasVersion;

				if(i>1)
				resultado = resultado + "," + " ";	
				}
			
			}			
			
			resultado = resultado + "]";
			
		} catch (Exception e) {System.out.println("Error DAO Ventas getDescargasContenidoY: " + e.getMessage()); }
		return resultado;
	}
	
	public static String obtenerMes(Date date){
		 String result="";
		 Calendar calendar=Calendar.getInstance();
		 calendar.setTime(date);
		 int month=0;
		 
		 try{
		   month=calendar.get(Calendar.MONTH);
		 }catch(Exception ex){}
		 switch(month){
		  case 0:
		    {
		      result="Enero";
		      break;
		    }
		  case 1:
		    {
		      result="Febrero";
		      break;
		    }
		  case 2:
		    {
		      result="Marzo";
		      break;
		    }
		  case 3:
		    {
		      result="Abril";
		      break;
		    }
		  case 4:
		    {
		      result="Mayo";
		      break;
		    }
		  case 5:
		    {
		      result="Junio";
		      break;
		    }
		  case 6:
		    {
		      result="Julio";
		      break;
		    }
		  case 7:
		    {
		      result="Agosto";
		      break;
		    }
		  case 8:
		    {
		      result="Septiembre";
		      break;
		    }
		  case 9:
		    {
		      result="Octubre";
		      break;
		    }
		  case 10:
		    {
		      result="Noviembre";
		      break;
		    }
		  case 11:
		    {
		      result="Diciembre";
		      break;
		    }
		  default:
		    {
		      result="Error";
		      break;
		    }
		 }
		 return result;
		}

	@Override
	public List<DataReclamo> getReclamos() throws Exception {
		List<DataReclamo> reclamos = new ArrayList<DataReclamo>();
		try {
		
			Query q = em.createQuery("select r from Reclamo r");

			if (q.getResultList() !=null ){
				int i=0;
				for(i=0; i<q.getResultList().size();i++){
				
					if(((Reclamo)q.getResultList().get(i)).getEstado().compareTo(Estado.ACTIVO.toString())==0){
						DataReclamo dr = new DataReclamo();
						DataVenta dv = new DataVenta();
						Reclamo aux = (Reclamo)q.getResultList().get(i);
						dr.setIdReclamo(aux.getIdReclamo());
						dr.setDescripcion(aux.getDescripcion());
						dr.setFecha(aux.getFecha());
				
						Version verAux = ((Reclamo)q.getResultList().get(i)).getVenta().getContenido();
						DataVersion dversion = new DataVersion();
						dversion.setNombre(verAux.getContDig().getDescripcion());
	
						DataCliente dcliente = new DataCliente();
						dcliente.setMail(aux.getVenta().getCliente().getMail());
						dv.setCliente(dcliente);
						
						ContenidoDigital cd = new ContenidoDigital();
						cd = aux.getVenta().getContenido().getContDig();
						DataContenidoDigital dcd = new DataContenidoDigital();
						dcd.setDescripcion(cd.getDescripcion());
	
						dversion.setContDig(dcd);
						dv.setVersion(dversion);
						dr.setVenta(dv);					
						reclamos.add(dr);
					}
				}
			} 
		}catch (Exception e) {
			System.out.println("Error DAO Ventas (Funcion getReclamos" + e.getMessage());}
		Collections.sort(reclamos);
		return reclamos;
	}

	
	@Override
	public List<DataContenidoDigital> getTopPagas() throws Exception{		
		List<DataContenidoDigital> lst = new ArrayList<DataContenidoDigital>();
		try {
			/*Query q = em.createQuery("SELECT * FROM CONTENIDODIGITAL C WHERE C.IDCONTENIDO IN (SELECT V.CONTDIG_IDCONTENIDO FROM VENTA VEN, VERSION V WHERE  VEN.CONTENIDO_IDVERSION = V.IDVERSION AND C.IDCONTENIDO = V.CONTDIG_IDCONTENIDO  AND V.CONTDIG_IDCONTENIDO = C.IDCONTENIDO AND V.PRECIO <> 0.0 ORDER BY V.CANTDESCRAGAS DESC)");*/
			Query q = em.createQuery("SELECT C FROM ContenidoDigital C WHERE C.idContenido IN (SELECT V.contDig.idContenido FROM Venta VEN, Version V WHERE  VEN.contenido.idVersion = V.idVersion AND C.idContenido = V.contDig.idContenido AND V.contDig.idContenido = C.idContenido AND V.precio <> 0.0 ORDER BY V.cantDescragas DESC)");
			@SuppressWarnings("unchecked")
			List<ContenidoDigital> cds = q.getResultList();
			for (ContenidoDigital contenidoDigital : cds) {
				lst.add(new DataContenidoDigital(contenidoDigital));
			}
		} catch (Exception e) {
			System.out.println("Error DAO Usuario Funcion obtenerTopPagas: " + e.getMessage());
		}	
		return lst;
	}
	
	
}


